<?php

class UserrightDAO {
	// debug-Logger
	static $debug;
	
	// Datenbank Objekt
	private $db;
	
	// Hier steht immer der aktuellste Fehler drin
	private $error = null;
	
	/**
	 * Der Konstruktor stattet die DAO mit einem DB Objekt aus
	 */
	function __construct() {
		if (!isset(self::$debug)) {
			self::$debug = DebugQuery::getInstance();
		}
		$this->db = DBFactory::getInstance();
	}
	
	/**
	 * Der Destruktor entfernt die Referen auf das DB Objekt
	 */
	function __destruct() {
		unset($this->db);
	}
	
	/**
	 * Diese Methode gibt ein array mit allen Userright Entitäten zurück.
	 * 
	 * Jedes Benutzerrecht wird hierbei durch ein Userright Objekt representiert.
	 * 
	 * @return numerisches array mit Userright Objekten, wenn erfolgreich, sonst null und Fehler in error
	 */
	public function get_all() {
		// Wenn vorher ein Fehler aufgetreten ist, schlucken
		$this->handle_previous_error();
		
		$ret = array();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Loading all entities of Userright from Database...\n");
			
		// Query zum laden aller Userright Objekte aus der DB
		$sql = 'SELECT
					UserID,
					RightID
				FROM
					Userright';
		
		// Query vorbereiten
		if (!$stmt = $this->db->prepare($sql)) {
			// Error in der DB Instanz
			$this->error = ERR_DATABASE_RETURNS_ERROR. $this->db->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in database object: %s\n", $this->error);
			
			return null;
		}
		
		// Query ausführen
		if (!$stmt->execute()) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// Ergebnis binden und auslesen
		$stmt->bind_result($userid, $rightid);
		while ($stmt->fetch()) {
			$ret[] = new Userright($userid, $rightid);
		}
		
		// Statement schließen
		$stmt->close();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Successfully loaded %d Userright objects from database\n", count($ret));
		
		return $ret;
	} 
	
	/**
	 * Diese Methode liest alle Entitäten von Userright mit der userid aus der Datenbank
	 * 
	 * @param integer $userid
	 * @return array von Userright wenn vorhanden, sonst null undFehler in error
	 */
	public function getByUserId($userid) {
		// Wenn vorher ein Fehler aufgetreten ist, schlucken
		$this->handle_previous_error();
		
		$ret = array();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Loading Userrights with userid '%d' from database...\n", $userid);
		
		// Query zum laden der Userright Entitäten mit der entsprechenden UserID
		$sql = 'SELECT
					UserID,
					RightID
				FROM
					Userright
				WHERE
					UserID = ?';
		
		// Query vorbereiten
		if (!$stmt = $this->db->prepare($sql)) {
			// Error in der DB Instanz
			$this->error = ERR_DATABASE_RETURNS_ERROR. $this->db->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in database object: %s\n", $this->error);
			
			return null;
		}
		
		// Platzhalter ersetzen
		$stmt->bind_param('i', $userid);
		
		// Query ausführen
		if (!$stmt->execute()) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// Ergebnis an variablen binden
		$stmt->bind_result($userid, $rightid);
		while($stmt->fetch()) {
			$ret[] = new Userright($userid, $rightid); 
		}
		
		// Statement schließen
		$stmt->close();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append(count($ret) > 0 ? "Loading Userright entities with userid '%d' was successfull.\n" : "No Userright entities found with userid '%d.\n", $userid);
		
		return $ret;
	}
	
	/**
	 * Diese Methode liest alle Entitäten von Userright mit der rightid aus der Datenbank
	 * 
	 * @param integer $rightid
	 * @return array von Userright wenn vorhanden, sonst null und  Fehler in error
	 */
	public function getByRightId($rightid) {
		// Wenn vorher ein Fehler aufgetreten ist, schlucken
		$this->handle_previous_error();
		
		$ret = array();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Loading Userrights with rightid '%d' from database...\n", $rightid);
		
		// Query zum laden der Userright Entitäten mit der entsprechenden UserID
		$sql = 'SELECT
					UserID,
					RightID
				FROM
					Userright
				WHERE
					RightID = ?';
		
		// Query vorbereiten
		if (!$stmt = $this->db->prepare($sql)) {
			// Error in der DB Instanz
			$this->error = ERR_DATABASE_RETURNS_ERROR. $this->db->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in database object: %s\n", $this->error);
			
			return null;
		}
		
		// Platzhalter ersetzen
		$stmt->bind_param('i', $rightid);
		
		// Query ausführen
		if (!$stmt->execute()) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// Ergebnis an variablen binden
		$stmt->bind_result($userid, $rightid);
		while($stmt->fetch()) {
			$ret[] = new Userright($userid, $rightid); 
		}
		
		// Statement schließen
		$stmt->close();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append(count($ret) > 0 ? "Loading Userright entities with rightid '%d' was successfull.\n" : "No Userright entities found with rightid '%d.\n", $rightid);
		
		return $ret;
	}
	
	/**
	 * Prüft ob es ein bestimmtes Recht gibt.
	 * 
	 * @param Userright $userright
	 * @return Userright das Benutzerrecht falls vorhanden, falls nicht null und Fehler in error
	 */
	public function exsists($userright) {
		// Wenn vorher ein Fehler aufgetreten ist, schlucken
		$this->handle_previous_error();
		
		$ret = null;
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Checking on Userright '%d => %d'\n", $userright->get_userid(), $userright->get_rightid());
		
		// Query zum löschen der Userright Entität
		$sql = 'SELECT
					UserID,
					RightID
				FROM
					Userright
				WHERE
					UserID = ? AND
					RightID = ?';
		
		// Statement vorbereiten
		if (!$stmt = $this->db->prepare($sql)) {
			// Error in der DB Instanz
			$this->error = ERR_DATABASE_RETURNS_ERROR. $this->db->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in database object: %s\n", $this->error);
			
			return null;
		}
		
		// Platzhalter ersetzen
		$stmt->bind_param('ii', $userright->get_userid(), $userright->get_rightid());
		
		// Query ausführen
		if (!$stmt->execute()) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// Ergebnis an variablen binden
		$stmt->bind_result($userid, $rightid);
		while($stmt->fetch()) {
			$ret = new Userright($userid, $rightid); 
		}
		
		// Statement schließen
		$stmt->close();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append($ret ? "Userright entity does exsist.\n" : "Userright entity does not exsist.\n");
		
		return $ret;
	}
	
	/**
	 * Diese Methode speichert ein Userright Entität in die Datenbank
	 * 
	 * @param Userright $userright die Entität
	 * @return ID, falls erfolgreich, sonst null und Fehler in error
	 */
	public function save($userright) {
		// Wenn vorher ein Fehler aufgetreten ist, schlucken
		$this->handle_previous_error();
		
		$ret = null;
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Saving the Userright entity '%s' to the database...", $userright );
		
		// Prüfen, ob es die Userright Entität schon gibt
		if ($this->exsists($userright)) {
			$this->error = ERR_USERRIGHT_ALREADY_EXSISTS. $userright->get_userid() .'=>'. $userright->get_rightid();
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->apped("The Userright was already set: %d => %d", $userright->get_userid(), $userright->get_rightid());
				
			return null;
		}
			
		// Query zum Speichern einer Userright Entität
		$sql = 'INSERT INTO
					Userright(UserID, RightID)
				VALUES
					(?, ?)';
		
		// Statement vorbereiten
		if (!$stmt = $this->db->prepare($sql)) {
			// Error in der DB Instanz
			$this->error = ERR_DATABASE_RETURNS_ERROR. $this->db->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in database object: %s\n", $this->error);
			
			return null;
		}
		
		// Platzhalter ersetzen
		$stmt->bind_param('ii', $userright->get_userid(), $userright->get_rigtid());
		
		// Query ausführen
		if (!$stmt->execute()) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// UserrightID auslesen
		$ret = $stmt->insert_id;
		
		// Gab es einen Fehler?
		if (!$ret) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// Statement schließen
		$stmt->close();
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Userright '%d => %d' was saved successfully.\n", $userright->get_userid(), $userright->get_rigtid());
		
		return $ret;
	}
	
	/**
	 * Diese Methode löscht die Userright Entität
	 * 
	 * @param Userright $userright
	 */
	public function delete($userright) {
		// Wenn vorher ein Fehler aufgetreten ist, schlucken
		$this->handle_previous_error();
		
		$ret = null;
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Deleting Userright '%d => %d'\n", $userright->get_userid(), $userright->get_rightid());
			
		// Query zum löschen der Userright Entität
		$sql = 'DELETE FROM
					Userright
				WHERE
					UserID = ? AND
					RightID = ?';
		
		// Statement vorbereiten
		if (!$stmt = $this->db->prepare($sql)) {
			// Error in der DB Instanz
			$this->error = ERR_DATABASE_RETURNS_ERROR. $this->db->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in database object: %s\n", $this->error);
			
			return null;
		}
		
		// Platzhalter ersetzen
		$stmt->bind_param('ii', $userright->get_userid(), $userright->get_rightid());
		
		// Query ausführen
		if (!$stmt->execute()) {
			// Error im Statement
			$this->error = ERR_STATEMENT_RETURNS_ERROR. $stmt->error;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Error in statment: %s\n", $this->error);
			
			return null;
		}
		
		// Statement schließen
		$stmt->close();
		
		// Probieren, ob es die Entität noch gibt
		if ($this->exsists($userright)) {
			// Löschen hat nicht geklappt
			$this->error = ERR_ENTITY_WAS_NOT_DELETED. $id;
			
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Userright '%d => %d' was not deleted.", $userright->get_userid(), $userright->get_rightid());
				
			return null;
		}
		
		// debug
		if (DEBUG_ENABLED)
			self::$debug->append("Userright entity successfully deleted.");
		
		return $ret;
	}
	
	/**
	 * Gibt den error aus und leert den internen error cache
	 */
	public function get_error() {
		$err = $this->error;
		$this->error = null;
		return $err;
	}
	
	/**
	 * Behandelt vorhergegangene nicht ausgelesene errors
	 */
	private function handle_previous_error() {
		// Falls vorher mal ein error aufgetreten ist, jedoch der
		// Fehler nicht ausgelesen wurde, wird dieser jetzt verworfen
		if ($pre_error = $this->get_error()) {
			// debug
			if (DEBUG_ENABLED)
				self::$debug->append("Previous error was not read: '%s'\n", $pre_error);
		}
	}
}

?>